package com.ld.security.common.core.util;


import cn.hutool.cache.CacheUtil;
import cn.hutool.cache.impl.TimedCache;
import cn.hutool.core.lang.Console;
import lombok.Getter;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * 计数器工具
 * @author ldl
 *
 */

public class CountUtil {

    @Getter
    static class  Node{
        //时间
        private final long nowTime;
        //存活时间
        private final long timeSize;
        //值
        private final Object value;

        public Node(Object value,long timeSize) {
            nowTime = System.currentTimeMillis();
            this.timeSize = timeSize;
            this.value = value;
        }
    }

    static TimedCache<String,Node> timedCache = CacheUtil.newTimedCache(1000);

    private static String getId(Object val){
        String json = JsonUtil.toJson(val);
        return UuidUtil.getId(json);
    }

    private static Node newNode(Object v,long timeSize){
        return new Node(v,timeSize);
    }


    /**
     * 得到目前自增的值
     * @param val
     * @return
     */
    public static long getIncrValue(Object val) {
        String key = getId(val);
        Node node =   timedCache.get(key);
        AtomicInteger atomicInteger;
        if(node != null){
            atomicInteger = (AtomicInteger)node.getValue();
            return  atomicInteger.get();
        }
        return -1;
    }

    /**
     * 返回指定值的生存时间 毫秒
     * @param val
     * @return
     */
    public static long ttl(Object val) {
        String key = getId(val);
        Node node =  timedCache.get(key);
        if(node != null){
           long x =  node.getNowTime()+node.getTimeSize();
           long y = System.currentTimeMillis();
           return x-y;
        }
        return -1;
    }

    /**
     * 将制定值自增并设置生存时间
     * @param val
     * @return
     */
    public static long incr(Object val,long timeSize) {
        String key = getId(val);
        Node node =  timedCache.get(key);
        AtomicInteger atomicInteger;
        if(node == null){
            atomicInteger= new AtomicInteger(0);
            node= newNode(atomicInteger,timeSize);
            timedCache.put(key,node,timeSize);
        }else{
            atomicInteger = (AtomicInteger)node.getValue();
        }
        return atomicInteger.incrementAndGet();
    }



}